package it.truestoryfactory.tsq.services.util;

import it.truestoryfactory.tsq.services.msg.TSMessage;

import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;

import android.util.Log;


public class SkeletonSingleton implements MessengerInterface {
	
	private static SkeletonSingleton istanza;
	
	private ServerSocket serverSocket=null;
	private Socket socket=null;
	private MessengerInterface server;
	public boolean canListen = true;
	
	private SkeletonSingleton(MessengerInterface serverImpl) {
		Log.d(this.getClass().getName(), "skeleton created");
		server = serverImpl;
		//canListen=true;
		try {
			this.serverSocket=new ServerSocket(8889);
			Log.d(this.getClass().getName(), "server socket created");
		} catch (BindException e) {
			Log.d(this.getClass().getName(), "already exits some thread listening");
			canListen  = false;
			e.printStackTrace();
		} catch (IOException e) {
			Log.d(this.getClass().getName(), "WTF!!!");
			e.printStackTrace();
		}
	}
	
	public static SkeletonSingleton getInstance(MessengerInterface serverImpl){
		if (istanza == null){
			Log.d("Primo ingresso ", "chiamo il costruttore di skeleton");

			istanza = new SkeletonSingleton(serverImpl);			
		}
		else Log.d("Secondo ingresso", "non chiamo il costruttore");
	    return istanza; 
	    }
	
	public void runSkeleton(){
		while(canListen) {
			Log.d(this.getClass().getName(), "thread " + Thread.currentThread().getName() + "listening");
			try {
				this.socket=this.serverSocket.accept();
				Log.d(this.getClass().getName(), "server socket accepted a conn from " + this.socket.getInetAddress().getHostAddress());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			if (!this.serverSocket.isClosed()) {
				SkeletonThread corrente = new SkeletonThread(this.socket, this);
				corrente.start();
			}
		}
		Log.d(this.getClass().getName(), "thread " + Thread.currentThread().getName() + "not listening!");
	}
	
	protected void finalize() throws Throwable {
		this.socket.close();
		this.serverSocket.close();
		Log.d(this.getClass().getName(), "thread " + Thread.currentThread().getName() + "not living!");
		super.finalize();
	}
	
	@Override
	public void sendMessage(String ipAddress, TSMessage msg){
		Log.d(this.getClass().getName(), "method sendMessage called by Skeleton!");
	}
	
	@Override
	public void receiveMessage(TSMessage tsMessage){
		server.receiveMessage(tsMessage);
	}

	public void closeAll() {
		
		try {
			serverSocket.close();
			canListen=false;
			istanza=null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
